home *** CD-ROM | disk | FTP | other *** search
- Path: news.larc.nasa.gov!amiga-request
- From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
- Subject: v91i085: Quiz 1.0 - question and answer program, Part02/02
- Reply-To: creubank@is.crl.sony.co.jp
- Newsgroups: comp.sources.amiga
- Message-ID: <comp.sources.amiga:v91i085@ab20.larc.nasa.gov>
- References: <comp.sources.amiga:v91i084@ab20.larc.nasa.gov>
- Date: 10 Apr 91 14:57:39 GMT
- Approved: tadguy@uunet.UU.NET (Tad Guy)
- X-Mail-Submissions-To: amiga@uunet.uu.net
- X-Post-Discussions-To: comp.sys.amiga.misc
-
- Submitted-by: creubank@is.crl.sony.co.jp
- Posting-number: Volume 91, Issue 085
- Archive-name: applications/quiz-1.0/part02
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 2)."
- # Contents: parse.c quiz.c screen.c
- # Wrapped by tadguy@ab20 on Wed Apr 10 10:57:36 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'parse.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'parse.c'\"
- else
- echo shar: Extracting \"'parse.c'\" \(11191 characters\)
- sed "s/^X//" >'parse.c' <<'END_OF_FILE'
- X/***
- X *** parse.c
- X ***
- X *** Curtis Eubanks
- X *** 3 November 1989
- X ***
- X ***/
- X
- X#include <stdio.h>
- X#include <string.h>
- X
- X#include <exec/types.h> /* only for def'n of 'node' */
- X#include <exec/lists.h> /* needed in qstructs.h */
- X
- X/*#ifndef EXEC_MEMORY_H
- X#include <exec/memory.h>
- X#endif
- X*/
- X#define GLOBALVAR extern
- X#include "qstructs.h"
- Xextern char *mymalloc();
- X
- Xvoid slistAdd();
- Xstruct slist *Makeslist();
- Xint slistSize();
- Xvoid remwh();
- Xchar *findfirstbrace();
- Xchar *findlevel();
- Xvoid deletebrackets();
- Xchar *snarfbrackets();
- Xvoid printslist();
- Xstruct slist *FindOrs();
- Xstruct slist *findors();
- Xint checkbrackets();
- Xstruct slist *joinslists();
- Xchar *findmatchbrace();
- Xstruct slist *expandslist();
- Xstruct slist *expand();
- X
- X/* Add a single string to slist sl. Does not copy */
- Xvoid slistAdd(sl,s) struct slist *sl; char *s;
- X{
- X while (sl->next) sl = sl->next;
- X sl->next = (struct slist *)mymalloc(sizeof(struct slist));
- X (sl->next)->s = s;
- X (sl->next)->next = NULL;
- X} /* slistAdd */
- X
- X/* returns the number of elems in sl */
- Xint slistSize(sl) struct slist *sl;
- X{
- X int rtn=0;
- X while (sl) rtn++, sl=sl->next;
- X return(rtn);
- X} /* slistSize */
- X
- X/* allocate and return a new slist structure and fill it with 's' */
- Xstruct slist *Makeslist(s) char *s;
- X{
- X struct slist *rtn;
- X rtn = (struct slist *)mymalloc(sizeof(struct slist));
- X rtn->s = s;
- X rtn->next = NULL;
- X return(rtn);
- X} /* Makeslist */
- X
- X/* whitespace macro */
- X#define iswhite(x) ((x == ' ')||(x == '\t'))
- X
- X/* modifies s by removing leading & trailing whitespace and replacing
- X any other whitespace with a single space */
- Xvoid remwh(s) char *s;
- X{
- X char *r;
- X r = s; /* start scanning at the beginning */
- X if (!(*s)) return; /* a null string could mess us up */
- X while (1) {
- X while ((*r) && iswhite(*r)) r++;
- X if (!(*r)) {
- X /* we may have to delete a single ' ' at the end */
- X /* since we already check for a null string passed to remwh, */
- X /* we know that *(s-1) is a valid address */
- X if (iswhite(*(s-1))) *(s-1) = '\0';
- X else *s = '\0';
- X return;
- X } /* if !*r */
- X /* now copy till next white */
- X while ((*r) && (!(iswhite(*r)))) *s++ = *r++;
- X if (*r) *s++ = ' '; /* replace white with a space */
- X } /* while (1) */
- X} /* remwh */
- X
- X/* returns the address of the first opening brace '{' in s.
- X If none found, returns NULL */
- Xchar *findfirstbrace(s)
- X char *s;
- X{
- X while (*s) {
- X if (*s == '{') return(s);
- X s++;
- X } /* while */
- X return(NULL);
- X} /* findfirstbrace */
- X
- X/* returns the address of first opening brace in s that is nested level
- X levels deep. Returns NULL if not found */
- Xchar *findlevel(s, level)
- X char *s;
- X int level;
- X{
- X int nest = 0;
- X
- X if (level == 0) return(s);
- X while (*s) {
- X if (*s == '{') {
- X nest++;
- X if (nest==level) return(s+1);
- X } /* if */
- X else if (*s == '}') nest--;
- X s++;
- X } /* while */
- Xreturn(NULL);
- X} /* findlevel */
- X
- X/* Modifies s by deleting the first set of matching brackets in s.
- X Requires s has at least one set of balanced brackets.
- X deletebrackets("this {is {an} example} here") --> modifies s to -->
- X "this is {an} example here" */
- Xvoid deletebrackets(s) char *s;
- X{
- X int nest = 1;
- X char *t;
- X
- X while (*s != '{') s++;
- X t = s+1;
- X while (*t) {
- X if (*t == '{') nest++;
- X else if (*t == '}') {
- X nest--;
- X if (!nest) { t++; break; } /* found end brace */
- X } /* else if */
- X *s++ = *t++;
- X } /* while *t */
- X while (*t) *s++ = *t++; /* copy the rest of the string */
- X *s = '\0';
- X} /* deletebrackets */
- X
- X/* snarfbrackets is the same as deletebrackets except that it actually
- X deletes everything within and including the brackets. Returns a NEW
- X string. Doesn't modify s. Requires the brackets exist.
- X snarfbrackets("this {is {an} example} here") = "this here" */
- Xchar *snarfbrackets(s)
- X char *s;
- X{
- X char *first, *last, *rtn;
- X
- X rtn = mymalloc(strlen(s)+1);
- X (void)strcpy(rtn, s);
- X first = findfirstbrace(rtn);
- X if (!first)
- X FatalError("Aiigghh! Couldn't find first brace in %s\n",rtn);
- X last = findmatchbrace(first)+1;
- X if (!last)
- X FatalError("Aiigghh! Couldn't find matching brace in %s\n",first);
- X while (*last) *first++ = *last++;
- X *first = '\0';
- X return(rtn);
- X}
- X
- X/* Prints out all the strings in an slist structure, each on a different
- X line. Used only for debugging */
- Xvoid printslist(sl) struct slist *sl;
- X{
- X printf("Slist is:\n");
- X while (sl) { printf(" \"%s\"\n",sl->s); sl = sl->next; }
- X printf("\n");
- X}
- X
- X/* FindOrs returns a list of outermost level strings of s that are
- X separated by '|'. Requires s have balanced brackets. If only one
- X string is found, NULL is returned.
- X FindOrs("one|{two|zwei|ni}|mikka") =
- X { "one", "{two|zwei|ni}", "mikka"} */
- Xstruct slist *FindOrs(s) char *s;
- X{
- X struct slist *rtn = NULL;
- X int tmpsize, numfound = 0, nest = 0;
- X char *lastword, *tmpstr;
- X
- X if (*s == '\0') return(rtn);
- X lastword = s;
- X while (*s) {
- X if (*s == '{') nest++;
- X else if (*s == '}') nest--;
- X if ((*s == '|')&&(!nest)) {
- X numfound++;
- X tmpsize = s-lastword+1;
- X tmpstr = mymalloc(tmpsize);
- X memcpy(tmpstr, lastword, tmpsize-1);
- X tmpstr[tmpsize-1] = '\0';
- X if (!rtn) rtn = Makeslist(tmpstr);
- X else slistAdd(rtn, tmpstr);
- X lastword = s+1;
- X } /* if */
- X s++;
- X } /* while */
- X if (numfound == 0) return(NULL);
- X if (*lastword) {
- X numfound++;
- X tmpsize = s-lastword+1;
- X tmpstr = mymalloc(tmpsize);
- X memcpy(tmpstr, lastword, tmpsize-1);
- X tmpstr[tmpsize-1] = '\0';
- X if (!rtn) rtn = Makeslist(tmpstr);
- X else slistAdd(rtn, tmpstr);
- X } /* if */
- X return(rtn);
- X} /* FindOrs */
- X
- X/* findors (probably not the best name) is similar to FindOrs, except
- X that it returns the '|'-separated strings between the first set of
- X balanced brackets. Requires at least one set of balanced braces.
- X findors("not in braces {a|b|{c|d}} not included") =
- X { "a", "b", "{c|d}" }
- X As with FindOrs, findors returns NULL if only a single string is
- X found or if s is an empty string or if no braces are found. This
- X was probably a bad idea. */
- Xstruct slist *findors(s) char *s;
- X{
- X struct slist *rtn = NULL;
- X int tmpsize, numfound = 0, nest = 1;
- X char *lastword, *tmpstr;
- X
- X if (*s == '\0') return(NULL);
- X
- X lastword = findfirstbrace(s);
- X if (!lastword) return(NULL); /* look ma, no braces */
- X lastword++; /* point to actual string, not brace */
- X s = lastword;
- X while (*s) {
- X if (*s=='{') nest++;
- X else if (*s=='}') {
- X nest--;
- X if (!nest) {
- X numfound++;
- X tmpsize = s-lastword+1;
- X tmpstr = mymalloc(tmpsize);
- X memcpy(tmpstr, lastword, tmpsize-1);
- X tmpstr[tmpsize-1] = '\0';
- X if (!rtn) rtn = Makeslist(tmpstr);
- X else slistAdd(rtn, tmpstr);
- X break;
- X } /* if !nest */
- X } /* if close bracket */
- X else if ((*s == '|') && (nest==1)) {
- X numfound++;
- X tmpsize = s-lastword+1;
- X tmpstr = mymalloc(tmpsize);
- X memcpy(tmpstr, lastword, tmpsize-1);
- X tmpstr[tmpsize-1] = '\0';
- X if (!rtn) rtn = Makeslist(tmpstr);
- X else slistAdd(rtn, tmpstr);
- X lastword = s+1;
- X } /* if */
- X s++;
- X } /* while */
- X if (numfound==1) return(NULL);
- X return(rtn);
- X } /* findors */
- X
- X/* Returns deepest level of bracket nesting in a regular expression
- X string. Returns -1 if there is an error (unbalanced or unmatched
- X brackets. */
- Xint checkbrackets(s) char *s;
- X{
- X int nest = 0, maxlevel = 0;
- X
- X while (*s) {
- X if (*s == '{') {
- X nest++;
- X if (nest > maxlevel) maxlevel = nest;
- X } /* if open brace */
- X else if (*s == '}') {
- X nest--;
- X if (nest < 0) return(-1);
- X } /* if close brace */
- X s++;
- X } /* while */
- X if (nest != 0) return(-1);
- X return(maxlevel);
- X} /* checkbrackets */
- X
- X/* Joins two slists by adding sl2 to the end of sl1. Does not copy
- X sl2. Modifies sl1. There's really no reason to return sl1... */
- Xstruct slist *joinslists(sl1, sl2)
- X struct slist *sl1, *sl2;
- X{
- X struct slist *tmpslist; /* so we can return sl1 */
- X
- X if (sl2) {
- X tmpslist = sl1;
- X while (tmpslist->next) tmpslist = tmpslist->next;
- X tmpslist->next = sl2;
- X } /* if sl2 */
- X return(sl1);
- X} /* joinslists */
- X
- X/* find and return pointer to a matching brace; requires such a
- X brace exists! Returns NULL if not found. */
- Xchar *findmatchbrace(s)
- X char *s;
- X{
- X int nest = 0;
- X
- X s = findfirstbrace(s);
- X while (*s) {
- X if (*s == '{') nest++;
- X else if (*s == '}') {
- X nest--;
- X if (nest==0) return(s);
- X } /* if close */
- X s++;
- X } /* while */
- X return(NULL);
- X} /* findmatchbrace */
- X
- X/* expandslist expects a list of strings. Each string is considered to
- X be a simple regular expression of using '{', '}', and '|'. The
- X strings are expanded to all possibilities indicated by the regexp.
- X "a|b|c" --> "a", "b", "c"
- X "{x|y|z}-axis" --> "x-axis", "y-axis", "z-axis"
- X "this {option} is fun" --> "this option is fun", "this is fun" */
- Xstruct slist *expandslist(sl)
- X struct slist *sl;
- X{
- X struct slist *tmpslist, *rtn = NULL, workslist, *braceslist;
- X char *bptr, *eptr, *newstr;
- X int beforelength, afterlength;
- X
- X workslist.next = NULL; /* used with a single string for efficiency */
- X while (sl) { /* repeat for each string in sl */
- X tmpslist = FindOrs(sl->s); /* get top level disjunctions */
- X if (!tmpslist) {tmpslist=&workslist;workslist.s=sl->s;}
- X while (tmpslist) {
- X if (bptr = findfirstbrace(tmpslist->s)) { /* there is a brace */
- X braceslist = findors(bptr); /* or tmpslist->s */
- X if (!braceslist) { /* "{degenerate case}" */
- X /* we want "{x}" to map to "x" and "" */
- X slistAdd(sl, snarfbrackets(tmpslist->s)); /* "" */
- X deletebrackets(tmpslist->s);
- X slistAdd(sl, tmpslist->s);
- X tmpslist = tmpslist->next;
- X continue;
- X } /* if "{x}" */
- X eptr = findmatchbrace(bptr) + 1;
- X beforelength = bptr - tmpslist->s;
- X afterlength = tmpslist->s + strlen(tmpslist->s) - eptr;
- X while (braceslist) {
- X newstr = mymalloc(beforelength+strlen(braceslist->s)+afterlength+1);
- X memcpy(newstr, tmpslist->s, beforelength);
- X strcat(newstr, braceslist->s);
- X strcat(newstr, eptr);
- X slistAdd(sl, newstr);
- X braceslist = braceslist->next;
- X } /* while */
- X } /* if there is a brace */
- X else { /* no brace, just add the string to return list */
- X if (!rtn) rtn = Makeslist(tmpslist->s);
- X else slistAdd(rtn, tmpslist->s);
- X } /* else */
- X tmpslist = tmpslist->next; /* iterate */
- X } /* while tmpslist */
- X sl = sl->next; /* iterate */
- X } /* while sl */
- X return(rtn);
- X} /* expandslist */
- X
- X/* expand expands a single string by calling expandslist. */
- X/* returns the expanded slist, or NULL if error */
- Xstruct slist *expand(s) char *s;
- X{
- X int level;
- X struct slist *rtn, *tmpslist;
- X
- X level = checkbrackets(s);
- X if (level<0) {
- X fprintf(stderr, "Unbalanced braces in \"%s\"\n", s);
- X return(NULL);
- X } /* if */
- X rtn = expandslist(Makeslist(s));
- X tmpslist = rtn;
- X while (tmpslist) {
- X remwh(tmpslist->s);
- X tmpslist = tmpslist->next;
- X } /* while */
- X return(rtn);
- X} /* expand */
- END_OF_FILE
- if test 11191 -ne `wc -c <'parse.c'`; then
- echo shar: \"'parse.c'\" unpacked with wrong size!
- fi
- # end of 'parse.c'
- fi
- if test -f 'quiz.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'quiz.c'\"
- else
- echo shar: Extracting \"'quiz.c'\" \(26723 characters\)
- sed "s/^X//" >'quiz.c' <<'END_OF_FILE'
- X/***
- X *** quiz.c
- X *** a question-answer game similar to /usr/games/quiz.
- X ***
- X *** Curtis Eubanks
- X *** 19 October 1989 -- CLI only
- X *** 18 November 1989 -- graphics interface
- X ***
- X ***/
- X
- X/* screen.c funcs */
- Xextern void InitGraphics(), CloseGraphics(), redraw(),
- X UpdateMenuGraphState();
- X
- X/* graph.c funcs */
- Xextern void cleargraph(),drawgraph(), UpdateCurrentQ();
- X
- X#include <exec/types.h>
- X#include <exec/lists.h>
- X#include <stdio.h>
- X#include <string.h>
- X#include <libraries/dos.h>
- X#include <libraries/dosextens.h>
- X#include <exec/memory.h>
- X#include <workbench/startup.h>
- X#include <stdlib.h> /* for srand & rand */
- X#include <intuition/intuition.h>
- X
- Xextern struct FileHandle *Open();
- Xextern long time();
- X/*#include <time.h> for time() */
- X
- X
- Xextern int bhandlemsg();
- Xextern ULONG ehandlemsg();
- Xextern struct NewWindow backnw;
- Xextern struct NewScreen ns;
- Xextern struct Window *backwindow;
- Xextern struct IntuiMessage *mes, *GetMsg();
- Xextern char *qtext, *atext, *sbuff, *ubuff, *ctext;
- Xextern struct StringInfo sStringInfo;
- Xextern void DrawQText();
- Xextern struct Gadget sgadget;
- X#define BEGINMENUNUM (SHIFTITEM(2)|SHIFTSUB(NOSUB))
- X
- X/* type definitions */
- X#define GLOBALVAR
- X#include "qstructs.h"
- X#include "parse.c.h"
- X#include "graph.h"
- X
- Xextern char *mymalloc(); /* in mymalloc.c */
- X
- X/* in graph.c */
- Xextern int readscore();
- Xextern int *AddTrial();
- Xextern void SetWorstQuestion();
- X
- X/***** function defs ******/
- Xvoid usage();
- Xvoid parseargs();
- Xstruct ResListItem *MakeNewItem();
- Xvoid FreeResource();
- Xvoid FreeAll();
- Xvoid CleanUp();
- Xchar *Allocate();
- Xvoid FatalError();
- Xvoid NonFatalError();
- Xint readfile();
- Xint countlines();
- Xint isin();
- Xchar *separate();
- Xvoid ask();
- Xvoid getinput();
- Xvoid correct();
- Xvoid wrong();
- Xchar **extractlines();
- Xvoid ilistAdd();
- Xilist *Makeilist();
- Xint ProcessQFile();
- Xvoid doswap();
- Xvoid stractivate();
- Xvoid MajorSwap();
- Xvoid quiz();
- Xvoid writescore();
- Xvoid main();
- X
- X
- X
- X
- Xvoid usage(s)
- X char *s;
- X{
- X printf("Usage: %s datafile [-switch] [-ignorecase] [-help]\n\n", s);
- X printf(" -switch: questions and answers are switched\n");
- X printf(" -ignorecase: case doesn't matter\n");
- X printf(" -help: print this message (duh...)\n\n");
- X printf(" You can use just the first letter of each option as\n");
- X printf(" well. datafile contains lines of the form\n");
- X printf(" question:answer (one on each line)\n");
- X exit(0);
- X}
- X
- X/* parses arguments and sets the appropriate qstate elements. */
- X/* iff quiz was called with a filename, qstate.File is a non-empty */
- X/* string. */
- Xvoid parseargs(argc, argv)
- X int argc;
- X union {
- X char **args;
- X struct WBStartup *msg;
- X } *argv;
- X{
- X if (argc==0) { /* Workbench startup */
- X /*ns.DefaultTitle = argv->args[0];*/
- X if (argv->msg->sm_NumArgs > 2)
- X NonFatalError("%s: only one quiz file can be selected!\n");
- X if (argv->msg->sm_NumArgs >= 2)
- X strncpy(qstate.File, argv->msg->sm_ArgList[1].wa_Name,MAXFILENAME);
- X }
- X else { /* CLI startup */
- X int i, gotfname=0;
- X for (i=1; i<argc; i++) {
- X
- X if ((!stricmp(argv->args[i], "-switch"))||
- X (!stricmp(argv->args[i], "/switch"))||
- X (!stricmp(argv->args[i], "-s")))
- X qstate.Switch = 1;
- X
- X else if ((!stricmp(argv->args[i], "-help"))||
- X (!stricmp(argv->args[i], "/help"))||
- X (!stricmp(argv->args[i], "-h")))
- X usage(argv->args[0]); /* exits */
- X
- X else if ((!stricmp(argv->args[i], "-ignorecase"))||
- X (!stricmp(argv->args[i], "/ignorecase"))||
- X (!stricmp(argv->args[i], "-i")))
- X qstate.CaseSensitive = 0;
- X
- X else if ((!stricmp(argv->args[i], "-dpen")) && (i+1 < argc))
- X backnw.DetailPen = atoi(argv->args[++i]);
- X
- X else if ((!stricmp(argv->args[i], "-bpen")) && (i+1 < argc))
- X backnw.BlockPen = atoi(argv->args[++i]);
- X
- X else if ((!stricmp(argv->args[i], "-sdpen")) && (i+1 < argc))
- X ns.DetailPen = atoi(argv->args[++i]);
- X
- X else if ((!stricmp(argv->args[i], "-sbpen")) && (i+1 < argc))
- X ns.BlockPen = atoi(argv->args[++i]);
- X
- X else if (gotfname)
- X NonFatalError("Quiz: unrecognized option: %s. Try -help\n",argv->args[i]);
- X else {
- X gotfname = 1;
- X strncpy(qstate.File, argv->args[i], MAXFILENAME);
- X } /* else */
- X } /* for i */
- X } /* CLI startup */
- X} /* parseargs */
- X
- Xstruct ResListItem *MakeNewItem(ptr, size, type)
- X char *ptr;
- X int size, type;
- X {
- X struct ResListItem *rtn;
- X extern char *AllocMem();
- X rtn = (struct ResListItem *)AllocMem(sizeof(struct ResListItem), MEMF_CLEAR);
- X if (rtn==NULL) {
- X fprintf(stderr, "Ummm. Big trouble: couldn't allocate NewItem\n");
- X CleanUp(DONE_MSG);
- X exit(-1); /* machine is really low on memory anyway */
- X } /* if */
- X rtn->ptr = ptr;
- X rtn->size = size;
- X rtn->type = type;
- X return(rtn);
- X} /* MakeNewItem */
- X
- Xvoid FreeResource(Item)
- X struct ResListItem *Item;
- X{
- Xswitch(Item->type) {
- X case ALLOC_TYPE:
- X if (Item->ptr) {
- X FreeMem(Item->ptr, Item->size); /* the real free */
- X Item->ptr = NULL;
- X } /* if */
- X break;
- X case LOCK_TYPE:
- X UnLock((struct FileLock *)Item->ptr);
- X break;
- X case LIB_TYPE: /* these should be the last items released! */
- X if (Item->ptr) CloseLibrary(Item->ptr); /* cast it to what? */
- X break;
- X case SCREEN_TYPE: /* should be 2nd to last item released! */
- X if (Item->ptr) CloseScreen((struct Screen *)Item->ptr);
- X break;
- X case WINDOW_TYPE: /* must be closed AFTER screen! */
- X if (Item->ptr) CloseWindow((struct Window *)Item->ptr);
- X break;
- X default:
- X NonFatalError("FreeResource: unknown resource type: %ld\n",Item->type);
- X break;
- X } /* switch */
- X} /* FreeResource */
- X
- X/* FreeAll will free all memory that has been allocated via Allocate() */
- Xvoid FreeAll(ResListp)
- X struct List *ResListp;
- X{
- X extern void ForgetMemory(); /* mymalloc.c */
- X struct ResListItem *node;
- X struct List TmpList;
- X
- X /* Here's the deal: we want to free all memory resources. We will
- X copy all non-memory resources into a temporary list, freeing up
- X the memory resources as we go along. */
- X
- X NewList(&TmpList);
- X
- X while (node = (struct ResListItem *)RemTail(ResListp)) {
- X if (node->type == ALLOC_TYPE) {
- X FreeResource(node); FreeMem(node, sizeof(struct ResListItem));
- X } /* if Alloc type */
- X else
- X AddTail(&TmpList, node);
- X } /* while */
- X /* this yields the original order */
- X NewList(ResListp);
- X while (node = (struct ResListItem *)RemTail(&TmpList))
- X AddTail(ResListp, node);
- X
- X ForgetMemory(); /* must do this!!! This lets mymalloc know to start
- X allocating new memory and forget the old chunks */
- X
- X} /* FreeAll */
- X
- X/* CleanUp keeps track of all resource allocations and will clean up
- X when passed DONE_MSG. Must be passed INIT_MSG initally */
- Xvoid CleanUp(msg, ptr, size)
- X int msg;
- X char *ptr;
- X int size;
- X{
- X struct ResListItem *NewItem;
- X static struct List ResList; /* this is the resource list */
- X struct ResListItem *node;
- X
- Xswitch (msg) {
- X case INIT_MSG:
- X NewList(&ResList); /* initialize resource list */
- X break;
- X case ALLOC_MSG:
- X /* first we have to allocate space for the NewItem. If */
- X /* this call fails, we're in big trouble. */
- X NewItem = MakeNewItem(ptr, size, ALLOC_TYPE);
- X
- X /* and add it to the list */
- X AddTail(&ResList, NewItem);
- X break;
- X
- X case LOCK_MSG:
- X /* lock resource type */
- X NewItem = MakeNewItem(ptr, 0, LOCK_TYPE); /* size not used */
- X AddTail(&ResList, &(NewItem->n));
- X break;
- X
- X case LIB_MSG:
- X /* library opened */
- X NewItem = MakeNewItem(ptr, 0, LIB_TYPE);
- X AddTail(&ResList, &(NewItem->n));
- X break;
- X
- X case NEWSCREEN_MSG:
- X NewItem = MakeNewItem(ptr, 0, SCREEN_TYPE);
- X AddTail(&ResList, &(NewItem->n));
- X break;
- X
- X case NEWWINDOW_MSG:
- X NewItem = MakeNewItem(ptr, 0, WINDOW_TYPE);
- X AddTail(&ResList, &(NewItem->n));
- X break;
- X
- X case FREEONE_MSG:
- X NonFatalError("FREEONE not implemented yet! Bogosity, dude.\n");
- X break;
- X
- X case FREEALL_MSG:
- X FreeAll(&ResList);
- X break;
- X
- X case DONE_MSG: /* this is really cleaning up */
- X while (node = (struct ResListItem *)RemTail(&ResList)) {
- X /* this depends on the fact that &node = &NewItem->n */
- X FreeResource(node);
- X if (node) {
- X FreeMem(node, sizeof(struct ResListItem)); /* overhead */
- X node = NULL;
- X } /* if */
- X }
- X break;
- X default:
- X NonFatalError("CleanUp: unknown message: %ld\n", msg);
- X break;
- X } /* switch */
- X} /* CleanUp */
- X
- Xchar *Allocate(size)
- X int size;
- X{
- X char *ptr;
- X extern char *AllocMem();
- X
- X/* ptr = AllocMem(size, MEMF_CLEAR);*/
- X ptr = mymalloc(size);
- X if (ptr==NULL)
- X FatalError("Out of memory! Couldn't allocate %ld bytes\n", size);
- X/* already registered in mymalloc */
- X#if 0
- X else CleanUp(ALLOC_MSG, ptr, size); /* register the resource */
- X#endif
- X return(ptr);
- X}
- X
- X/* NonFatalError */
- Xvoid NonFatalError(s, a1, a2, a3, a4, a5)
- X char *s, *a1, *a2, *a3, *a4, *a5;
- X{
- Xfprintf(stderr, s, a1, a2, a3, a4, a5);
- X}
- X
- X/* prints error message string s (w/optional format strings) , cleans
- X up and exits */
- Xvoid FatalError(s, a1, a2, a3, a4, a5)
- X char *s, *a1, *a2, *a3, *a4, *a5;
- X{
- X fprintf(stderr, s, a1 ,a2, a3, a4, a5);
- X CloseGraphics();
- X CleanUp(DONE_MSG);
- X exit(10);
- X}
- X
- X/* read the file into one enormous buffer */
- X/* returns 1 if successful, 0 if not */
- X
- Xint readfile(name,thebuffer)
- X char *name, **thebuffer;
- X{
- X struct FileInfoBlock *fib;
- X extern struct FileLock *Lock();
- X struct FileLock *lock;
- X struct FileHandle *fh;
- X int filesize,success,bytesread;
- X
- X /* fib must be longword aligned!!! */
- X fib = (struct FileInfoBlock *)Allocate(sizeof(struct FileInfoBlock));
- X#ifdef DEBUG
- Xprintf("FileInfoBlock is at %d\n", fib);
- X#endif
- X lock = Lock(name, ACCESS_READ);
- X if (!lock) {
- X NonFatalError("%s not found!\n", name);
- X return 0;
- X } /* if */
- X /* Normally, we could call
- X CleanUp(LOCK_MSG, (char *)lock, 0);
- X to register the resource; but we'll just unlock after we're
- X done so that the user can swap disks w/o trouble */
- X success = Examine(lock, fib);
- X if (!success) {
- X NonFatalError("Couldn't examine %s!\n", name);
- X UnLock(lock); /* we're done with the lock */
- X return 0;
- X }
- X
- X#ifdef DEBUG
- X/*---------------------------------------------------------------*/
- Xprintf("Name: %s\n", fib->fib_FileName);
- Xprintf("[%d] ", fib->fib_DirEntryType);
- Xif (fib->fib_DirEntryType>0) printf("Directory.\n");
- X else printf("Plain file.\n");
- Xprintf("file size in bytes: %d\n", fib->fib_Size);
- Xprintf(" in blocks: %d\n", fib->fib_NumBlocks);
- Xprintf("file comment: %s\n", fib->fib_Comment);
- X/*printf("Last modified: \n"); ShowDate(&(fib->fib_Date));*/
- X/*---------------------------------------------------------------*/
- X#endif
- X
- X filesize = fib->fib_Size; /* file size */
- X UnLock(lock); /* we're done with the lock */
- X
- X *thebuffer=Allocate(filesize+1); /* add a '\0' to end */
- X
- X fh = Open(name, MODE_OLDFILE);
- X if (!fh) {
- X NonFatalError("Couldn't open %s\n", name);
- X return 0;
- X }
- X bytesread = Read(fh, *thebuffer, filesize);
- X if (bytesread != filesize) {
- X FatalError("Couldn't read %ld bytes from %s\n",filesize,name);
- X Close(fh);
- X return 0;
- X }
- X (*thebuffer)[filesize] = '\0';
- X Close(fh);
- X return 1;
- X} /* readfile */
- X
- X/* count the number of lines that are separated by a newline in
- X buffer */
- Xint countlines(buffer)
- X char *buffer;
- X{
- X int count=0, i=0;
- X while (buffer[i]) if (buffer[i++]=='\n') count++;
- X if (buffer[i-1] != '\n') count++; /* printf("No terminating newline\n");*/
- X /*else printf("Terminating newline\n");*/
- X return(count);
- X} /* countlines */
- X
- X/* returns 1 if s is in sl, 0 otherwise */
- Xint isin(sl, s)
- X struct slist *sl;
- X char *s;
- X{
- X if (qstate.CaseSensitive)
- X while(sl) {
- X if (!strcmp(sl->s, s)) return(1);
- X sl=sl->next;
- X } /* while */
- X else
- X while(sl) {
- X if (!stricmp(sl->s, s)) return(1);
- X sl=sl->next;
- X } /* while */
- X return(0);
- X} /* isin */
- X
- X/* separate finds the ':' in a string "a:b" and replaces it with '\0'
- X then return a pointer to b. Modifies s. */
- Xchar *separate(s) char *s;
- X{
- X while (*s) {
- X if (*s==':') { *s = '\0'; return(s+1);}
- X s++;
- X } /* while */
- X return(NULL); /* no ':' found */
- X} /* separate */
- X
- X/* q is the question string */
- Xvoid ask(q, sofar, total)
- X char *q;
- X int sofar, total;
- X{
- X
- X printf("[%ld/%ld] %s: ", sofar, total, q); }
- X
- X/* a is answer string */
- Xvoid getinput(a) char *a; {
- X
- X gets(a); remwh(a); }
- X
- X/* if he gets it right */
- Xvoid correct() { printf("Right!\n"); }
- X
- X/* if wrong */
- Xvoid wrong(wrongi, right)
- X struct slist *right;
- X char *wrongi;
- X{
- X int num;
- X
- X/* if user just pressed return be nice; at least he admits his ignorance */
- Xif (*wrongi) printf("Wrong, dummy. ");
- X num = slistSize(right);
- X if (num == 1) printf("\"%s\"\n", right->s);
- X else {
- X printf("\n");
- X while(right->next) printf(" \"%s\" or\n", right->s),right=right->next;
- X printf(" \"%s\"\n",right->s);
- X } /* else */
- X} /* wrong */
- X
- X/* extractlines finds n strings each separated by a '\n'. Creates and
- X fills an array that is the start address of each string. Replaces
- X '\n' with '\0' */
- Xchar **extractlines(n,bigbuf)
- X int n;
- X char *bigbuf;
- X{
- X char **rtn;
- X int i=0, j=0;
- X
- X rtn = (char **)Allocate(n * sizeof(char *));
- X rtn[0]=bigbuf;
- X while (bigbuf[i]) { /* j is in case there's no terminating newline */
- X if (bigbuf[i] == '\n') {
- X rtn[++j] = &(bigbuf[i])+1;
- X bigbuf[i] = '\0';
- X } /* if */
- X i++;
- X } /* while */
- X
- X return(rtn);
- X} /* extractlines */
- X
- X/* delete any blank lines in a buffer s */
- Xvoid deleteblanklines(s)
- X char *s;
- X{
- X char *t;
- X t = s;
- X /* get rid of any initial blank lines */
- X while (*t == '\n') t++;
- X while (1) {
- X /* t now points to first char in a non-empty line */
- X while (*t != '\n') {
- X if (*t == '\0') {*s = '\0'; return;}
- X *s++ = *t++;
- X }
- X while (*t == '\n') t++;
- X *s++='\n'; /* put one in */
- X } /* while 1 */
- X} /* deleteblanklines */
- X
- X/* add an int to an ilist */
- Xvoid ilistAdd(il, i)
- X ilist *il;
- X int i;
- X{
- X while (il->next) il = il->next;
- X il->next = (ilist *)Allocate(sizeof(ilist));
- X (il->next)->i = i;
- X (il->next)->next = NULL;
- X} /* ilistAdd */
- X
- X/* create and return a new ilist */
- Xilist *Makeilist(i) int i;
- X{
- X ilist *rtn;
- X rtn = (ilist *)Allocate(sizeof(ilist));
- X rtn->i = i; rtn->next = NULL;
- X return(rtn);
- X} /* Makeilist */
- X
- X/***
- X *** This function should be called after a quiz file has been read
- X *** in via readfile(). The file will be in buf at that time.
- X ***
- X *** ProcessQFile will delete blank lines, count lines, and parse
- X *** them. Note that all parameters are modified. Chotto abunai ne.
- X ***
- X *** *n is set to the number of lines.
- X *** *answers, *questions, *score, *origorder are all allocated.
- X *** A lot of other stuff will be allocated by subroutines. When
- X *** this quiz file is to be discarded, all allocated memory should
- X *** be free via FreeAll().
- X ***
- X *** Answers and questions will be swapped if qstate.Switch. A
- X *** random order is calculated as well.
- X ***
- X *** Returns the number of questions.
- X ***
- X ***/
- Xint ProcessQFile(answers, questions, score, origorder, preprocess, numq)
- X struct slist ***answers, ***questions;
- X short **score, **origorder;
- X int preprocess, numq;
- X{
- X /***
- X *** lines contains pointers to the beginning each line of
- X *** the quiz file.
- X *** tmpans is used in extracting the answer from each line.
- X ***
- X ***/
- X char **lines,*tmpans;
- X int n,i; /* n is the number of questions */
- X
- X /***
- X *** tmpslist and tmpptr are used for swapping
- X ***/
- X struct slist *tmpslist;
- X short tmpshort;
- X if (preprocess) {
- X deleteblanklines(buf);
- X n = countlines(buf);
- X
- X lines = extractlines(n,buf);
- X if (qstate.GraphType = readscore(n)) cleargraph(),drawgraph();
- X UpdateMenuGraphState();
- X *answers = (struct slist **)Allocate(n * sizeof(struct slist *));
- X *questions = (struct slist **)Allocate(n * sizeof(struct slist *));
- X *score = (short *)Allocate(n * sizeof(short)); /* initializes to 0 */
- X *origorder = (short *)Allocate(n * sizeof(short));
- X
- X history = *score; hindices = *origorder;
- X for (i=0; i<n; i++) {
- X (*origorder)[i]=(short)i;
- X /* now find the answer in "question:answer" line */
- X tmpans = separate(lines[i]); /* modifies buf */
- X
- X /* this error should really just abort this particular file
- X and not actually exit. Later... */
- X if (!tmpans)
- X FatalError("Line \"%s\" is missing a colon\n", lines[i]);
- X
- X (*questions)[i] = expand(lines[i]);
- X (*answers)[i] = expand(tmpans);
- X
- X } /* for */
- X
- X if (qstate.Switch) doswap(answers, questions);
- X
- X } /* if preprocess */
- X else n = numq; /* if preprocess, n is passed in as last arg */
- X
- X /* calculate a random order */
- X srand((unsigned)time(NULL)); /* time is in seconds; where's utime? */
- X for (i=0;i<n;i++) (*score)[i] = 0; /* can't be done in loop below */
- X
- X for (i= 0; i<n; i++) {
- X int j, k;
- X /* swap questions j & k */
- X j=rand() % n; k = rand() % n;
- X if (j != k) {
- X tmpslist = (*questions)[j];
- X (*questions)[j] = (*questions)[k];
- X (*questions)[k] = tmpslist;
- X
- X tmpslist = (*answers)[j];
- X (*answers)[j] = (*answers)[k];
- X (*answers)[k] = tmpslist;
- X
- X tmpshort = (*origorder)[j];
- X (*origorder)[j] = (*origorder)[k];
- X (*origorder)[k] = tmpshort;
- X } /* if */
- X } /* for */
- X return(n);
- X } /* ProcessQFile */
- X
- X
- Xvoid doswap(a,q)
- X struct slist ***a, ***q;
- X{
- X struct slist **tmpptr;
- X tmpptr=*a;*a=*q;*q=tmpptr;
- X} /* doswap */
- X
- Xvoid stractivate()
- X{
- X ActivateGadget(&sgadget, backwindow, NULL);
- X} /* stractivate */
- X
- X/* swaps elements i and j of qs, as, ss, and os */
- Xvoid MajorSwap(qs, as, ss, os, i, j)
- X short ss[], os[];
- X struct slist *as[], *qs[];
- X int i, j;
- X{
- X short tmpshort;
- X struct slist *tmpslist;
- X
- X tmpslist = qs[i];
- X qs[i] = qs[j];
- X qs[j] = tmpslist;
- X
- X tmpslist = as[i];
- X as[i] = as[j];
- X as[j] = tmpslist;
- X
- X tmpshort = ss[i];
- X ss[i] = ss[j];
- X ss[j] = tmpshort;
- X
- X tmpshort = os[i];
- X os[i] = os[j];
- X os[j] = tmpshort;
- X} /* MajorSwap */
- X
- Xvoid quiz()
- X {
- X /***
- X *** answers is a list of valid answers
- X *** questions--a list of valid questions
- X ***
- X *** tmpslist is used for swapping
- X ***
- X ***/
- X struct slist **answers, **questions;
- X
- X /***
- X *** total is the total number of correct answers given.
- X *** n is the number of questions in the file.
- X *** gaveup = 1 if the user quits in the midde of this test.
- X *** if this is the case, a score file will NOT be written
- X ***
- X ***/
- X int i=0,n=0,total=0,gaveup=0,j;
- X
- X /* score is an array of shorts--one for each question. Initially,
- X score[i] = 0. If the user answers a question right the first time,
- X score[i] = RIGHT. If he gets it wrong, score is decremented and
- X the question is asked again later. Each time he gets it wrong,
- X score[i] is decremented until score[i] == MAXWRONG. If the user
- X gets it right, score[i] = -score[i] and thus tells how many times it
- X took to get it right. */
- X
- X /***
- X *** origorder[n] is a list of shorts that gives the original index
- X *** of each quiz line. Remember, these get shuffled around since
- X *** a random order is selected, and missed questions get stuck at
- X *** the end.
- X ***
- X ***/
- X short *score, *origorder;
- X ULONG val;
- X
- X /* initialize values */
- X fileinit:
- X i=0,n=0,total=0,gaveup=0,val=IGNORE;
- X
- X strcpy(sStringInfo.Buffer, "");
- X sStringInfo.BufferPos = 0;
- X sStringInfo.DispPos = 1;
- X
- X /* if we are in an asking state, process the question file */
- X if (qstate.Asking)
- X n = ProcessQFile(&answers, &questions, &score, &origorder, 1, 0);
- X
- X
- X qtext = NULL; atext = NULL; ctext = NULL;
- X if (qstate.Asking)
- X {
- X qtext = questions[i]->s;
- X /* DrawQText(); necessary? we call redraw */
- X }
- X
- X UpdateCurrentQ(0, (int)origorder[i]);
- X redraw();
- X stractivate();
- X
- X/* main loop */
- Xquizloop:
- Xwhile ((i<n)||(!qstate.Asking)) {
- X WaitPort(backwindow->UserPort); /* be nice */
- X while (mes = GetMsg(backwindow->UserPort)) val=bhandlemsg(mes);
- X
- X switch (val) {
- X case QUITNOW:
- X return; /* quit */
- X
- X case ABORTNOW:
- X val = IGNORE;
- X OnMenu(backwindow, BEGINMENUNUM);
- X qstate.Asking = 0;
- X qstate.ShowingAns = 0;
- X qtext = NULL;
- X
- X strcpy(sStringInfo.Buffer, "");
- X sStringInfo.BufferPos = 0;
- X sStringInfo.DispPos = 1;
- X redraw();
- X stractivate();
- X break;
- X /* abort */
- X
- X case OPENNEWFILE:
- X val=IGNORE;
- X qstate.Asking=1;
- X OffMenu(backwindow, BEGINMENUNUM);
- X goto fileinit; /* filename already set */
- X
- X case SWITCHEM:
- X doswap(&answers, &questions);
- X if (qstate.Asking) {
- X qtext = questions[i]->s;
- X DrawQText();
- X } /* if */
- X break; /* if switchem */
- X
- X case STARTASKING:
- X if ((!qstate.Asking) && qstate.File[0]) {
- X qstate.Asking = 1;
- X i=0,total=0,gaveup=0,val=IGNORE;
- X OffMenu(backwindow, BEGINMENUNUM);
- X ProcessQFile(&answers, &questions, &score, &origorder, 0, n);
- X qtext = questions[i]->s;
- X UpdateCurrentQ(currentquestion, (int)origorder[i]);
- X DrawQText();
- X if (qstate.GraphType) drawgraph();
- X stractivate();
- X } /* if */
- X break; /* STARTASKING */
- X
- X case NEWSTRING:
- X if (qstate.Asking) {
- X remwh(atext);
- X if (isin(answers[i], atext)) {
- X /* correct();*/
- X if (score[i]==0) score[i] = RIGHT,total++;
- X else score[i] = -score[i];
- X if (qstate.ShowingAns) {
- X qstate.ShowingAns = 0;
- X EraseCText();
- X } /* if */
- X } /* if isin */
- X
- X else { /* got this one wrong */
- X /* wrong(atext,answers[i]);*/
- X score[i]--;
- X if (score[i] <= MAXWRONG) {
- X i++;
- X ctext = NULL;
- X qstate.ShowingAns = 0;
- X EraseCText();
- X if (i>=n) break;
- X else
- X { /* do next question */
- X qtext = questions[i]->s;
- X DrawQText();
- X strcpy(sStringInfo.Buffer, "");
- X sStringInfo.BufferPos = 0;
- X sStringInfo.DispPos = 1;
- X RefreshGadgets(&sgadget, backwindow, NULL);
- X stractivate();
- X UpdateCurrentQ(currentquestion, (int)origorder[i]);
- X continue;
- X } /* else */
- X
- X } /* give up on this question */
- X else {
- X ctext = answers[i]->s; /* use the first legal answer I guess */
- X qstate.ShowingAns = 1;
- X DrawCText();
- X } /* else */
- X
- X /* we want to ask again, so put the question back */
- X /* swap with the last element */
- X MajorSwap(questions, answers, score, origorder, i, n-1);
- X i--;
- X
- X } /* else wrong */
- X
- X strcpy(sStringInfo.Buffer, "");
- X sStringInfo.BufferPos = 0;
- X sStringInfo.DispPos = 1;
- X i++;
- X if (i>=n) break;
- X qtext = questions[i]->s;
- X DrawQText();
- X UpdateCurrentQ(currentquestion, (int)origorder[i]);
- X
- X } /* if asking */
- X break; /* if a new string */
- X
- X case DISPLAYQ:
- X if (qstate.Asking) {
- X int theq=-1;
- X /* so we want to swap the current question with newquestion */
- X /* newquestion refers to the original order, so we have to find */
- X /* it first */
- X for (j=0; j<n; j++) if (origorder[j]==newquestion) theq=j;
- X if (theq==-1) {
- X NonFatalError("Couldn't find that question out of %d!\n",n);
- X break; /* from switch */
- X } /* if */
- X
- X if (i== theq) break;
- X /* if theq<i, then we already asked this question and should decrement
- X i so that we don't lose any new questions */
- X if (theq<i) i--;
- X MajorSwap(questions, answers, score, origorder, i, theq);
- X qtext = questions[i]->s;
- X
- X UpdateCurrentQ(currentquestion,(int)origorder[i]);
- X
- X strcpy(sStringInfo.Buffer, "");
- X sStringInfo.BufferPos = 0;
- X sStringInfo.DispPos = 1;
- X
- X redraw();
- X stractivate();
- X
- X } /* if asking */
- X break; /* DISPLAYQ */
- X case IGNORE:
- X break;
- X default:
- X NonFatalError("quiz(): %d is an unknown message\n", val);
- X break;
- X } /* switch val */
- X
- X stractivate();
- X RefreshGadgets(&sgadget, backwindow, NULL);
- X
- X val=IGNORE;
- X} /* while i<=n */
- X
- X qstate.Asking = 0;
- X qstate.ShowingAns = 0;
- X qtext = NULL; /* so it won't be redraw()n */
- X OnMenu(backwindow, BEGINMENUNUM);
- X strcpy(sStringInfo.Buffer, "");
- X sStringInfo.BufferPos = 0;
- X sStringInfo.DispPos = 1;
- X RefreshGadgets(&sgadget, backwindow, NULL);
- X stractivate();
- X
- X if (total != n) {
- X printf("You missed:\n");
- X for (i=0;i<n;i++)
- X /* score[i] is 0 if "quit" was selected */
- X if ((score[i] != RIGHT)&&(score[i] != 0))
- X printf(" %s: %s\n",questions[i]->s,answers[i]->s);
- X } /* if total != n */
- X else printf("Congratulations!\n");
- X printf("\nScore: %ld/%ld (%ld%%)\n", total, n, total * 100 / n);
- X if (gaveup==0){
- X writescore(score, n, origorder, total);
- X if (qstate.GraphType==0) {
- X qstate.GraphType = BYQUESTION;
- X UpdateMenuGraphState();
- X/* OffMenu(backwindow, (SHIFTMENU(1)|SHIFTITEM(4)|SHIFTSUB(NOSUB)));
- X OnMenu(backwindow, (SHIFTMENU(1)|SHIFTITEM(3)|SHIFTSUB(NOSUB)));*/
- X } /* if */
- X } /* if */
- X if (qstate.GraphType) {cleargraph(); drawgraph();}
- X i = 0;
- X EraseQText(); EraseCText(); /* does nothing if they are empty */
- X goto quizloop;
- X} /* quiz */
- X
- X/* write the score to filename.sc, also updates graph data */
- Xvoid writescore(score, n, value, total)
- X short *score, *value;
- X int n, total;
- X{
- X char scorefile[MAXFILENAME+3]; /* ".sc" */
- X FILE *fh;
- X int i, worstq;
- X strcpy(scorefile,qstate.File); strcat(scorefile,SCORE_FILE_EXT);
- X fh = fopen(scorefile,"a");
- X if (fh==NULL) NonFatalError("Couldn't open score file %s\n",scorefile);
- X else {
- X int *intptr;
- X intptr = AddTrial(n-total,n);
- X
- X worstq = intptr[0];
- X for (i=0;i<n;i++) {
- X/*printf("%d: orig=%d trialdata[%d]=%d worst=%d\n",
- X i,value[i],value[i],intptr[value[i]],worstq);*/
- X if (score[i] != RIGHT) {
- X fprintf(fh, "%d ", value[i]);
- X intptr[value[i]]++;
- X } /* if */
- X if (intptr[value[i]] > worstq) worstq = intptr[value[i]];
- X } /* for */
- X fprintf(fh, "\n");
- X fclose(fh);
- X /* only set worst question if he actually missed something */
- X if (n-total) SetWorstQuestion(worstq);
- X } /* else */
- X
- X} /* writescore */
- X
- Xvoid main(argc, argv)
- X int argc;
- X union {
- X char **args;
- X struct WBStartup *msg;
- X } argv;
- X{
- X
- X CleanUp(INIT_MSG); /* initialize resource manager */
- X
- X qstate.Switch = 0;
- X qstate.File[0] = '\0';
- X qstate.ShowingAns = 0;
- X qstate.CaseSensitive = 1;
- X qstate.Asking = 0;
- X qstate.GraphType = 0;
- X
- X parseargs(argc, &argv);
- X
- X if (qstate.File[0]) {
- X if (readfile(qstate.File,&buf))
- X qstate.Asking = 1;
- X else strcpy(qstate.File, "");
- X } /* if */
- X
- X InitGraphics();
- X redraw();
- X
- X quiz();
- X CloseGraphics();
- X CleanUp(DONE_MSG);
- X exit(0);
- X} /* main */
- END_OF_FILE
- if test 26723 -ne `wc -c <'quiz.c'`; then
- echo shar: \"'quiz.c'\" unpacked with wrong size!
- fi
- # end of 'quiz.c'
- fi
- if test -f 'screen.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'screen.c'\"
- else
- echo shar: Extracting \"'screen.c'\" \(17829 characters\)
- sed "s/^X//" >'screen.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <string.h> /* strcpy */
- X#include "screen.h"
- X
- Xvoid DrawRaisedText();
- Xvoid EraseQText(), EraseCText();
- Xvoid DrawQText(), DrawCText();
- Xvoid colorwindow();
- Xint OpenLibs();
- Xvoid InitGraphics();
- Xvoid UpdateMenuGraphState();
- Xvoid CloseGraphics();
- XULONG ehandlemsg();
- Xint handlegadget();
- Xint handlebuttons();
- Xint bhandlemsg();
- Xint handlemenu();
- Xvoid main();
- Xvoid redraw();
- Xvoid about(), abort();
- Xint load();
- X
- Xextern void stractivate(); /* quiz.c */
- X
- Xextern void drawgraph(), cleargraph(); /* graph.c */
- Xextern int whichquestion(); /* graph.c */
- X
- X
- X/* draw semi-3d-looking text */
- Xvoid DrawRaisedText(rp,text,slen,x,y)
- X struct RastPort *rp;
- X char *text;
- X int slen, x, y;
- X {
- X /* draw it dark */
- X SetAPen(rp, GREY2);
- X Move(rp, x+1,y);
- X Text(rp, text, slen);
- X
- X /* draw it light */
- X SetAPen(rp, GREY11);
- X Move(rp, x-1,y);
- X Text(rp, text, slen);
- X
- X /* draw it just right */
- X SetAPen(rp, GREY7);
- X Move(rp, x,y);
- X Text(rp, text, slen);
- X} /* DrawRaisedText */
- X
- X/* clear qtext display area */
- Xvoid EraseQText() {
- X if (qpb[0])
- X { /* clear area */
- X SetAPen(rp, GREY7);
- X SetDrMd(rp, JAM1);
- X RectFill(rp, qpt[2], qpt[3], qpb[2], qpb[3]);
- X qpb[0] = 0;
- X } /* if */
- X} /* EraseQText */
- X
- X#define QCOLOR GREY3
- X/* draw the question */
- Xvoid DrawQText()
- X{
- X int slen,theight,textsize;
- X
- X /* delete old border */
- X if (qpb[0]) /* don't delete if first time */
- X {
- X /* clear the area */
- X SetAPen(rp, GREY7);
- X SetDrMd(rp, JAM1);
- X RectFill(rp, qpt[2], qpt[3], qpb[2], qpb[3]);
- X } /* if */
- X slen = strlen(qtext);
- X if (slen==0) return;
- X theight = rp->TxHeight;
- X textsize = slen * rp->TxWidth + 1; /* 1 pixel pad? */
- X qpt[0] = QX-BORDWIDTH*2;
- X qpt[1] = QY+theight+BORDWIDTH*2;
- X qpt[2] = QX-BORDWIDTH*2;
- X qpt[3] = QY-BORDWIDTH*2;
- X qpt[4] = QX+textsize+BORDWIDTH*2;
- X qpt[5] = QY-BORDWIDTH*2;
- X
- X qpb[0] = QX-BORDWIDTH*2;
- X qpb[1] = QY+theight+BORDWIDTH*2;
- X qpb[2] = QX+textsize+BORDWIDTH*2;
- X qpb[3] = QY+theight+BORDWIDTH*2;
- X qpb[4] = QX+textsize+BORDWIDTH*2;
- X qpb[5] = QY-BORDWIDTH*2;
- X
- X if (slen <= maxqchars) {
- X /* set border */
- X DrawBorder(rp,&qtop,0,0);
- X /* draw black box */
- X SetAPen(rp, QCOLOR);
- X SetDrMd(rp, JAM1);
- X RectFill(rp, qpt[2]+BORDWIDTH, qpt[3]+BORDWIDTH,
- X qpb[2]-BORDWIDTH, qpb[3]-BORDWIDTH);
- X /* now draw text */
- X DrawRaisedText(rp, qtext, slen, QX, QY+baseheight);
- X } /* if */
- X else { /* must make bigger window */
- X char *lastspace = NULL, *s, *r;
- X int done = 0, numlines = 0, maxlen = 0, i;
- X /* Have to copy strings and output them after breaking up */
- X /* qtext. We must know maxlen's value in order to draw */
- X /* the dark grey rectangle */
- X char brokentext[MAXLINES][MAXQCHARS];
- X int sizes[MAXLINES];
- X r = qtext;
- X
- X do {
- X numlines++;
- X s = r;
- X while (s<r+maxqchars) {
- X if (*s == ' ') lastspace = s;
- X else if (*s == '\0') {done = 1; break;}
- X s++;
- X } /* while */
- X /* this is gross */
- X /* we found a line */
- X if (lastspace) {
- X if (!done) *lastspace = '\0'; /* gulp */
- X slen = strlen(r); if (slen>maxlen) maxlen = slen;
- X strncpy(brokentext[numlines-1],r,slen);
- X sizes[numlines-1] = slen;
- X /*DrawRaisedText(rp, r, slen, QX, QY+baseheight+theight*(numlines-1));*/
- X if (!done) *lastspace = ' ';
- X r = lastspace + 1;
- X while (*r == ' ') r++; /* skip over any more spaces */
- X if (!*r) done = 1;
- X lastspace = NULL;
- X } /* if lastspace */
- X else if (done) /* reached the end in this iteration */
- X {
- X slen = strlen(r); if (slen>maxlen) maxlen = slen;
- X strncpy(brokentext[numlines-1],r,slen);
- X sizes[numlines-1] = slen;
- X /*DrawRaisedText(rp, r, slen, QX, QY+baseheight+theight*(numlines-1));*/
- X }
- X else { /* no breaks */
- X strncpy(brokentext[numlines-1],r,maxqchars);
- X sizes[numlines-1] = maxqchars;
- X /*DrawRaisedText(rp, r, maxqchars, QX, QY+baseheight+theight*(numlines-1));*/
- X r+=maxqchars; maxlen = maxqchars;
- X while (*r == ' ') r++; /* skip over any more spaces */
- X if (!*r) done = 1;
- X } /* else */
- X } while ((!done)&&(numlines<MAXLINES));
- X /* set border -- only 3 must be changed*/
- X textsize = maxlen * rp->TxWidth + 1; /* 1 pixel pad? */
- X
- X qpt[4] = QX+textsize+BORDWIDTH;
- X qpb[2] = QX+textsize+BORDWIDTH;
- X qpb[4] = QX+textsize+BORDWIDTH;
- X
- X qpt[1] = QY+theight*numlines+BORDWIDTH;
- X qpb[1] = QY+theight*numlines+BORDWIDTH;
- X qpb[3] = QY+theight*numlines+BORDWIDTH;
- X
- X DrawBorder(rp,&qtop,0,0);
- X /* draw black box */
- X SetAPen(rp, QCOLOR);
- X SetDrMd(rp, JAM1);
- X RectFill(rp, qpt[2]+BORDWIDTH, qpt[3]+BORDWIDTH,
- X qpb[2]-BORDWIDTH, qpb[3]-BORDWIDTH);
- X
- X /* now actually draw the text */
- X for (i=0;i<numlines;i++)
- X DrawRaisedText(rp, brokentext[i], sizes[i], QX, QY+baseheight+theight*i);
- X } /* else */
- X} /* DrawQText */
- X
- X/* clear ctext display area */
- Xvoid EraseCText() {
- X if (cpb[0])
- X { /* clear area */
- X SetAPen(rp, GREY7);
- X SetDrMd(rp, JAM1);
- X RectFill(rp, cpt[2], cpt[3], cpb[2], cpb[3]);
- X cpb[0] = 0;
- X } /* if */
- X} /* EraseCText */
- X
- X#define CCOLOR 15 /* ? */
- X/* draw the correct answer */
- Xvoid DrawCText()
- X{
- X int slen, theight, textsize;
- X /* delete old border if existing */
- X if (cpb[0])
- X { /* clear area */
- X SetAPen(rp, GREY7);
- X SetDrMd(rp, JAM1);
- X RectFill(rp, cpt[2], cpt[3], cpb[2], cpb[3]);
- X } /* if */
- X if (ctext==NULL) return;
- X slen = strlen(ctext);
- X if (slen==0) return;
- X theight = rp->TxHeight;
- X textsize = slen * rp->TxWidth + 1; /* 1 pixel pad? */
- X
- X cpt[0] = CX-BORDWIDTH*2;
- X cpt[1] = CY+theight+BORDWIDTH*2;
- X cpt[2] = CX-BORDWIDTH*2;
- X cpt[3] = CY-BORDWIDTH*2;
- X cpt[4] = CX+textsize+BORDWIDTH*2;
- X cpt[5] = CY-BORDWIDTH*2;
- X
- X cpb[0] = CX-BORDWIDTH*2;
- X cpb[1] = CY+theight+BORDWIDTH*2;
- X cpb[2] = CX+textsize+BORDWIDTH*2;
- X cpb[3] = CY+theight+BORDWIDTH*2;
- X cpb[4] = CX+textsize+BORDWIDTH*2;
- X cpb[5] = CY-BORDWIDTH*2;
- X
- X if (slen <= maxqchars) {
- X /* set border */
- X DrawBorder(rp,&ctop,0,0);
- X /* draw black box */
- X SetAPen(rp, CCOLOR);
- X SetDrMd(rp, JAM1);
- X RectFill(rp, cpt[2]+BORDWIDTH, cpt[3]+BORDWIDTH,
- X cpb[2]-BORDWIDTH, cpb[3]-BORDWIDTH);
- X /* now draw text */
- X DrawRaisedText(rp, ctext, slen, CX, CY+baseheight);
- X } /* if */
- X else { /* must make bigger window */
- X char *lastspace = NULL, *s, *r;
- X int done = 0, numlines = 0, maxlen = 0, i;
- X /* Have to copy strings and output them after breaking up */
- X /* ctext. We must know maxlen's value in order to draw */
- X /* the dark grey rectangle */
- X char brokentext[MAXLINES][MAXQCHARS];
- X int sizes[MAXLINES];
- X r = ctext;
- X
- X do {
- X numlines++;
- X s = r;
- X while (s<r+maxqchars) {
- X if (*s == ' ') lastspace = s;
- X else if (*s == '\0') {done = 1; break;}
- X s++;
- X } /* while */
- X /* this is gross */
- X /* we found a line */
- X if (lastspace) {
- X if (!done) *lastspace = '\0'; /* gulp */
- X slen = strlen(r); if (slen>maxlen) maxlen = slen;
- X strncpy(brokentext[numlines-1],r,slen);
- X sizes[numlines-1] = slen;
- X if (!done) *lastspace = ' ';
- X r = lastspace + 1;
- X while (*r == ' ') r++; /* skip over any more spaces */
- X if (!*r) done = 1;
- X lastspace = NULL;
- X } /* if lastspace */
- X else if (done) /* reached the end in this iteration */
- X {
- X slen = strlen(r); if (slen>maxlen) maxlen = slen;
- X strncpy(brokentext[numlines-1],r,slen);
- X sizes[numlines-1] = slen;
- X }
- X else { /* no breaks */
- X strncpy(brokentext[numlines-1],r,maxqchars);
- X sizes[numlines-1] = maxqchars;
- X r+=maxqchars; maxlen = maxqchars;
- X while (*r == ' ') r++; /* skip over any more spaces */
- X if (!*r) done = 1;
- X } /* else */
- X } while ((!done)&&(numlines<MAXLINES));
- X /* set border -- only 3 must be changed*/
- X textsize = maxlen * rp->TxWidth + 1; /* 1 pixel pad? */
- X
- X cpt[4] = CX+textsize+BORDWIDTH;
- X cpb[2] = CX+textsize+BORDWIDTH;
- X cpb[4] = CX+textsize+BORDWIDTH;
- X
- X cpt[1] = CY+theight*numlines+BORDWIDTH;
- X cpb[1] = CY+theight*numlines+BORDWIDTH;
- X cpb[3] = CY+theight*numlines+BORDWIDTH;
- X
- X DrawBorder(rp,&ctop,0,0);
- X /* draw black box */
- X SetAPen(rp, CCOLOR);
- X SetDrMd(rp, JAM1);
- X RectFill(rp, cpt[2]+BORDWIDTH, cpt[3]+BORDWIDTH,
- X cpb[2]-BORDWIDTH, cpb[3]-BORDWIDTH);
- X
- X /* now actually draw the text */
- X for (i=0;i<numlines;i++)
- X DrawRaisedText(rp, brokentext[i], sizes[i], CX, CY+baseheight+theight*i);
- X } /* else */
- X} /* DrawCText */
- X
- X/* fills in an entire window with color c */
- Xvoid colorwindow(w,c)
- X struct Window *w;
- X int c;
- X{
- X SetDrMd(w->RPort, JAM1);
- X SetAPen(w->RPort, c);
- X RectFill(w->RPort, 0, 0, w->Width, w->Height);
- X} /* colorwindow*/
- X
- X#if 0
- Xvoid FatalError(s) char *s;
- X{
- X printf("%s", s);
- X CloseGraphics();
- X exit(1);
- X} /* FatalError */
- X#endif
- X
- X/* Just opens intuition library. Returns 1 if successful, 0 if not */
- Xint iopen=0, gopen=0;
- Xint OpenLibs() {
- X IntuitionBase = (struct IntuitionBase *)
- X OpenLibrary("intuition.library", 0);
- X if (IntuitionBase==NULL) return(0);
- X iopen = 1;
- X GfxBase = (struct GfxBase *)
- X OpenLibrary("graphics.library", 0);
- X if (GfxBase==NULL) return(0);
- X gopen=1;
- X return(1);
- X } /* OpenLibs */
- X
- Xvoid InitGraphics() {
- X if (OpenLibs()==0) FatalError("Couldn't open libraries!\n");
- X
- X if ((qscreen = OpenScreen(&ns)) == NULL)
- X FatalError("Couldn't open screen!\n");
- X vp = &(qscreen->ViewPort);
- X
- X /* initialize colortable */
- X LoadRGB4(vp, &mycmap[0], 32);
- X
- X/* errnw.Screen = qscreen;*/
- X backnw.Screen = qscreen;
- X
- X backnw.FirstGadget = &sgadget;
- X if ((backwindow = OpenWindow(&backnw)) == NULL)
- X FatalError("Couldn't open backdrop window!\n");
- X/* if ((ewindow = OpenWindow(&errnw)) == NULL)
- X FatalError("Couldn't open error window!\n");*/
- X
- X menustrip[0] = &m1;
- X menustrip[1] = &m2;
- X menustrip[0]->NextMenu = menustrip[1];
- X SetMenuStrip(backwindow,menustrip[0]);
- X
- X if (qstate.Asking || (!qstate.File[0]))
- X OffMenu(backwindow, BEGINMENUNUM);
- X if (qstate.GraphType==BYTRIAL) {
- X OffMenu(backwindow, TRIALMENUNUM);
- X OnMenu(backwindow, QUESTMENUNUM);
- X } /* if */
- X else if (qstate.GraphType==BYQUESTION)
- X {
- X OffMenu(backwindow, QUESTMENUNUM);
- X OnMenu(backwindow, TRIALMENUNUM);
- X } /* if */
- X ShowTitle(qscreen, FALSE);
- X rp = backwindow->RPort;
- X
- X /* calculate how many characters can fit in one line of text */
- X /* note that this method doesn't account for variable-width fonts :-( */
- X maxqchars = (MAXQX-QX)/rp->TxWidth;
- X baseheight = rp->TxBaseline;
- X } /* InitGraphics */
- X
- X/* This is not very clean, but we need to be able to turn off/on the
- X correct menu items depending of the state of the graph */
- Xvoid UpdateMenuGraphState() {
- X if (qstate.GraphType==BYTRIAL) {
- X OffMenu(backwindow, TRIALMENUNUM);
- X OnMenu(backwindow, QUESTMENUNUM);
- X } /* if */
- X else if (qstate.GraphType == BYQUESTION) {
- X OffMenu(backwindow, QUESTMENUNUM);
- X OnMenu(backwindow, TRIALMENUNUM);
- X } /* if */
- X} /* UpdateMenuGraphState */
- X
- Xvoid CloseGraphics()
- X{
- X if (backwindow) {
- X ClearMenuStrip(backwindow);
- X while (mes = GetMsg(backwindow->UserPort)) ReplyMsg(mes);
- X CloseWindow(backwindow);
- X } /* if backwindow */
- X if (qscreen) CloseScreen(qscreen);
- X if (gopen) CloseLibrary(GfxBase);
- X if (iopen) CloseLibrary(IntuitionBase);
- X /*OpenWorkBench();*/
- X /*WBenchToFront();*/
- X} /* CloseGraphics */
- X
- XULONG ehandlemsg(message)
- X struct IntuiMessage *message;
- X{
- X struct IntuiMessage localms;
- X int i;
- X UBYTE *s, *d;
- X ULONG class,code;
- X
- X s = (UBYTE *)message;
- X d = (UBYTE *)&localms;
- X
- X for (i=0;i<sizeof(struct IntuiMessage);i++) *d++=*s++;
- X ReplyMsg(message);
- X
- X class = localms.Class;
- X code = localms.Code;
- X switch (class)
- X {
- X case CLOSEWINDOW:
- X break;
- X case REFRESHWINDOW:
- X case NEWSIZE:
- X redraw();
- X default:
- X break;
- X } /* switch */
- X return(class);
- X} /* ehandlemsg */
- X
- Xint handlegadget(g)
- X struct Gadget *g;
- X{
- X switch (g->GadgetID) {
- X case STRINGID:
- X atext = ((struct StringInfo *)(g->SpecialInfo))->Buffer;
- X /*DrawQText();*/
- X return(NEWSTRING);
- X break;
- X case IMAGEID:
- X break;
- X default:
- X break;
- X }
- X return(IGNORE);
- X
- X} /* handle gadget */
- X
- Xvoid about() { printf("Quiz by Curtis Eubanks\n"); }
- X
- X/* returns 1 if successful, 0 if not */
- Xint load() {
- X if (*sStringInfo.Buffer)
- X {
- X strcpy(qstate.File, sStringInfo.Buffer);
- X history = hindices = (short *)NULL;
- X CleanUp(FREEALL_MSG);
- X if (readfile(qstate.File, &buf)) {
- X qstate.Asking = 1;
- X return 1;
- X } /* if */
- X } /* if */
- X return 0;
- X} /* load */
- X
- Xvoid abort() {
- X } /* abort */
- Xint handlemenu(code)
- X ULONG code;
- X{
- X ULONG MenuNumber = MENUNUM(code), ItemNumber = ITEMNUM(code);
- X if ((code != MENUNULL) && (ItemNumber != NOITEM)) {
- X if (MenuNumber == PROJMENU) {
- X switch (ItemNumber)
- X {
- X case QUITNUM:
- X return(QUITNOW);
- X break;
- X case ABOUTNUM:
- X about();
- X break;
- X case LOADNUM:
- X if (load()) return(OPENNEWFILE); else return(IGNORE);
- X break;
- X case BEGINNUM:
- X return(STARTASKING);
- X break;
- X default:
- X NonFatalError("Unknown Project Menu selection!\n");
- X break;
- X } /* switch */
- X } /* if project menu */
- X else if (MenuNumber==OPTMENU) {
- X switch (ItemNumber)
- X {
- X case SWITCHNUM:
- X return(SWITCHEM);
- X break;
- X case IGNORENUM:
- X qstate.CaseSensitive = !qstate.CaseSensitive;
- X break;
- X case ABORTNUM:
- X abort();
- X return(ABORTNOW);
- X break;
- X case MENUBYTRIAL:
- X if (qstate.GraphType != BYTRIAL && qstate.GraphType) {
- X qstate.GraphType = BYTRIAL;
- X OffMenu(backwindow, TRIALMENUNUM);
- X OnMenu(backwindow, QUESTMENUNUM);
- X cleargraph();
- X drawgraph();
- X stractivate();
- X }
- X return IGNORE;
- X break;
- X case MENUBYQUESTION:
- X if (qstate.GraphType != BYQUESTION && qstate.GraphType) {
- X qstate.GraphType = BYQUESTION;
- X OffMenu(backwindow, QUESTMENUNUM);
- X OnMenu(backwindow, TRIALMENUNUM);
- X cleargraph();
- X drawgraph();
- X stractivate();
- X }
- X return IGNORE;
- X break;
- X default:
- X NonFatalError("Unknown Option Menu selection!\n");
- X break;
- X } /* switch itemnumber */
- X } /* if option menu */
- X } /* if non-null menu selection */
- X return(IGNORE);
- X} /* handlemenu */
- X
- X/* handle button presses */
- Xint handlebuttons(code, mousex, mousey)
- X ULONG code;
- X SHORT mousex, mousey;
- X{
- X if (code == SELECTDOWN) {
- X int q;
- X#ifdef DEBUG
- X printf("mouse at %d, %d\n", mousex, mousey);
- X#endif
- X if ((qstate.GraphType == BYQUESTION) &&
- X ((q=whichquestion(mousex, mousey))!=-1))
- X { /* in graph.c */
- X newquestion = q; /* global, yucky */
- X return DISPLAYQ;
- X } /* if q != -1 */
- X } /* if code */
- X return IGNORE;
- X} /* handlebuttons */
- X
- X
- X
- Xint bhandlemsg(message)
- X struct IntuiMessage *message;
- X{
- X struct IntuiMessage localms;
- X int i;
- X UBYTE *s, *d;
- X ULONG class,code;
- X
- X s = (UBYTE *)message;
- X bloop:
- X d = (UBYTE *)&localms;
- X
- X /* copy message */
- X for (i=0;i<sizeof(struct IntuiMessage);i++) *d++=*s++;
- X ReplyMsg(message);
- X
- X class = localms.Class;
- X code = localms.Code;
- X switch (class)
- X {
- X case REFRESHWINDOW: /* ugh. this hurts */
- X /* any more REFRESHWINDOW msgs waiting? */
- X if (mes = GetMsg(backwindow->UserPort))
- X { /* don't redraw if more than one REFRESHWINDOW in a row */
- X/* printf("waiting: %d ",mes->Class);
- X if (mes->Class==REFRESHWINDOW) printf("(refresh)\n");
- X else printf("(not refresh)\n");*/
- X s = (UBYTE *)mes; message = mes; /* legal? */
- X if (mes->Class==REFRESHWINDOW) goto bloop;
- X else { /* some other message. Redraw and process it */
- X redraw();
- X goto bloop;
- X } /* else */
- X } /* if */
- X else redraw();
- X break;
- X case GADGETUP:
- X return(handlegadget((struct Gadget *)localms.IAddress));
- X break;
- X case MENUPICK:
- X return(handlemenu(code));
- X break;
- X case MOUSEBUTTONS:
- X return(handlebuttons(code, localms.MouseX, localms.MouseY));
- X break;
- X default:
- X break;
- X } /* switch */
- X return(IGNORE);
- X} /* bhandlemsg */
- X
- X#if 0
- Xvoid main(argc, argv)
- X int argc;
- X union {
- X char **args;
- X struct WBStartup *msg;
- X } argv;
- X{
- X ULONG val=0;
- X if (argc>2) {
- X/* errnw.DetailPen = atoi(argv.args[1]);
- X errnw.BlockPen = atoi(argv.args[2]);*/
- X }
- X if (argc>4) {
- X ns.DetailPen = atoi(argv.args[3]);
- X ns.BlockPen = atoi(argv.args[4]);
- X }
- X
- X InitGraphics();
- X
- X redraw();
- X /* WaitPort(ewindow->UserPort);*/
- X while(1) {
- X while (mes = GetMsg(backwindow->UserPort)) val=bhandlemsg(mes);
- X if (val == QUITNUM) break;
- X/* while (mes = GetMsg(ewindow->UserPort)) val=ehandlemsg(mes);*/
- X if (val == CLOSEWINDOW) break;
- X }
- X CloseGraphics();
- X} /* main */
- X#endif
- X#define BaseX 30
- X#define BaseY 40
- X#define Bsize 12
- X
- Xvoid redraw() {
- X colorwindow(backwindow, GREY7);
- X SetDrMd(rp, JAM1);
- X
- X /* draw gadget's border */
- X DrawBorder(rp,&ibt,0,0);
- X if (qtext) DrawQText();
- X if (qstate.ShowingAns) DrawCText();
- X if (qstate.GraphType) drawgraph();
- X RefreshGadgets(&sgadget, backwindow, NULL);
- X } /* redraw */
- END_OF_FILE
- if test 17829 -ne `wc -c <'screen.c'`; then
- echo shar: \"'screen.c'\" unpacked with wrong size!
- fi
- # end of 'screen.c'
- fi
- echo shar: End of archive 2 \(of 2\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
- Mail comments to the moderator at <amiga-request@uunet.uu.net>.
- Post requests for sources, and general discussion to comp.sys.amiga.misc.
-